package com.ly.nethub.config

import io.netty.channel.ChannelInboundHandlerAdapter
import io.netty.channel.ChannelOutboundHandlerAdapter

/**
 * 长连接配置项
 * todo ssl认证配置
 */
typealias EncoderCreator = () -> ChannelOutboundHandlerAdapter
typealias DecoderCreator = () -> ChannelInboundHandlerAdapter

data class NetHubOptions(
    val communicationProtocol: CommunicationProtocol, //通讯协议
    val connectTimeout: Long,//连接超时时间 毫秒
    val reconnectInterval: Long,//重连间隔时间 毫秒
    val reconnectTimes: Int,//单一地址重连次数
    val heartbeatMode: HeartbeatMode,
    val foregroundHeartbeatInterval: Long,//前台心跳间隔 毫秒
    val backgroundHeartbeatInterval: Long,//后台心跳间隔 毫秒
    val maxRetryCount: Int,//任务重发次数
    val resendInterval: Long, //任务重发时间间隔 毫秒
    val encoders: List<EncoderCreator>, //编码器列表
    val decoders: List<DecoderCreator>,//解码器列表
)

class NetHubBuilder {
    private var communicationProtocol: CommunicationProtocol =
        CommunicationProtocol.TCP(emptyList()) //通讯协议
    private var connectTimeout: Long = NetHubConfig.CONNECT_TIMEOUT//连接超时时间 毫秒
    private var reconnectInterval: Long = NetHubConfig.RECONNECT_INTERVAL //重连间隔时间 毫秒
    private var reconnectTimes: Int = NetHubConfig.RECONNECT_TIMES//单一地址重连次数
    private var heartbeatMode: HeartbeatMode = HeartbeatMode.Standard
    private var foregroundHeartbeatInterval: Long =
        NetHubConfig.FOREGROUND_HEARTBEAT_INTERVAL//前台心跳间隔 毫秒
    private var backgroundHeartbeatInterval: Long =
        NetHubConfig.BACKGROUND_HEARTBEAT_INTERVAL//后台心跳间隔 毫秒
    private var maxRetryCount: Int = NetHubConfig.MAX_RETRY_COUNT
    private var resendInterval: Long = NetHubConfig.RESEND_INTERVAL// 重发消息时间间隔 毫秒
    private var encoders: List<EncoderCreator> = emptyList()//编码器列表
    private var decoders: List<DecoderCreator> = emptyList()//解码器列表


    fun setCommunicationProtocol(protocol: CommunicationProtocol) {
        this.communicationProtocol = protocol
    }

    fun setConnectTimeout(timeout: Long) {
        this.connectTimeout = timeout
    }

    fun setReconnectInterval(interval: Long) {
        this.reconnectInterval = interval
    }

    fun setReconnectTimes(times: Int) {
        this.reconnectTimes = times
    }

    fun setHeartbeatMode(mode: HeartbeatMode) {
        this.heartbeatMode = mode
    }

    fun setForegroundHeartbeatInterval(interval: Long) {
        this.foregroundHeartbeatInterval = interval
    }

    fun setBackgroundHeartbeatInterval(interval: Long) {
        this.backgroundHeartbeatInterval = interval
    }

    fun setResendInterval(interval: Long) {
        this.resendInterval = interval
    }

    fun setMaxRetryCount(count: Int) {
        this.maxRetryCount = count
    }


    fun setEncoders(encoders: List<EncoderCreator>) {
        this.encoders = encoders
    }

    fun setDecoders(decoders: List<DecoderCreator>) {
        this.decoders = decoders
    }


    fun build(): NetHubOptions {
        val protocol = communicationProtocol
        if (protocol is CommunicationProtocol.TCP) {
            assert(protocol.ips.isNotEmpty()) {
                "ips list must be not empty"
            }
        }
        if (protocol is CommunicationProtocol.WebSocket) {
            assert(protocol.hosts.isNotEmpty()) {
                "hosts list must be not empty"
            }
        }
        assert(encoders.isNotEmpty()) {
            "encoder must be not empty"
        }
        assert(decoders.isNotEmpty()) {
            "decoder must be not empty"
        }
        return NetHubOptions(
            communicationProtocol = protocol,
            connectTimeout = connectTimeout,
            reconnectInterval = reconnectInterval,
            reconnectTimes = reconnectTimes,
            heartbeatMode = heartbeatMode,
            foregroundHeartbeatInterval = foregroundHeartbeatInterval,
            backgroundHeartbeatInterval = backgroundHeartbeatInterval,
            maxRetryCount = maxRetryCount,
            resendInterval = resendInterval,
            encoders = encoders,
            decoders = decoders
        )
    }
}

/**
 * 长连接配置项
 * 地址、编码器、解码器、不可以为空
 * @exception IllegalStateException
 */
fun netHubOptions(block: NetHubBuilder.() -> Unit): NetHubOptions {
    val builder = NetHubBuilder()
    builder.block()
    return builder.build()
}

